package modulesAPI.v2.composite;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Set;

import com.caterina.components.CLabel;
import com.caterina.components.CPanel;
import com.caterina.resources.CModules;
import com.caterina.resources.CWords;

import budget.Budget;
import budget.Service;
import modulesAPI.v2.composite.MRequest;
import modulesAPI.v2.Module;
import modulesAPI.v2.ViewType;
import modulesAPI.v2.basics.ModCalendar;
import modulesAPI.v2.basics.ModCollectionViewer;
import modulesAPI.v2.basics.ModDoubleTextField;
import modulesAPI.v2.basics.ModTextField;

public class MBudget extends Module<Budget>{
	/**
	 * Crea un nuovo modulo per l'inserimento/rappresentazione di un preventivo
	 * */
	public MBudget(Module<?> ownerModule, Budget content,Collection<Service>allServices, String tag, String description, ViewType viewType,int...options) {
		super(ownerModule, content, tag, description, viewType,options);
		this.allServices=allServices;
		this.createModules();
		this.addModules(request,lastDate,allowedServices,serviceTotal,adjustements,total);
	}
	private void createModules(){
		this.createStandardView();
	}
	private void createStandardView(){
		request = new MRequest(this, this.getContent().getRequest(), "REQUEST", "REQUEST_DESC", ViewType.READ_ONLY,MRequest.VIEW_MORE_LESS);	
		lastDate = new ModCalendar(this, this.getContent().getLastDate(), "BUDGET_LAST_DATE", "BUDGET_LAST_DATE_DESC", ViewType.READ_ONLY);
		serviceTotal = new ModTextField(this, Double.toString(this.getContent().getTotalCostWhitoutAdjustment()), "SERVICE_TOTAL_COST_DESC", "SERVICE_TOTAL_COST", ViewType.READ_ONLY);
		adjustements = new ModDoubleTextField(this, this.getContent().getAdjustments(), "BUDGET_ADJUSTMENTS", "BUDGET_ADJUSTMENTS_DESC", this.getViewType());
		total=new ModTextField(this, Double.toString(this.getContent().getTotal()), "BUDGET_TOTAL_COST", "BUDGET_TOTAL_COST_DESC", ViewType.READ_ONLY);
		allowedServices=this.createServicesModule(this.allServices,this.getContent().getServices());
	}
	private ModCollectionViewer createServicesModule(Collection <Service> allServices,Collection <Service> services){
		//inserisco tutti i servizi disponibili settandoli a 0 in dei moduli
		HashMap <Service,Integer> servicesMap =new HashMap<Service, Integer>();//Contiene tutti i servizi
		for(Service srv: allServices){
			servicesMap.put(srv, 0);
		}
		//Per ogni servizio conteggio il numero di occorrenze all' interno di quelli selezionati
		Set <Service> servSet=servicesMap.keySet();
		for(Service selectedServ: services){	
			for(Service servbyset:servSet){
				if(servbyset.equals(selectedServ))
					servicesMap.put(servbyset, servicesMap.get(servbyset)+1);
			}
		}
		//Creo i moduli dei servizi conteggiati
		ArrayList <MService> servicesMods=new ArrayList<MService>();
		for(Service serv:servSet){
			 MService srvcModule = new MService(null, serv,servicesMap.get(serv),"SERVICE", "SERVICE", ViewType.READ_ONLY, servicesMap.get(serv));
			 servicesMods.add(srvcModule);
			 srvcModule.addModuleChangedListener(this);
		}
		//Sposto in alto i servizi selezionati già (Facoltativo)
		LinkedList<Module<?>> sortedServices=new LinkedList<Module<?>>();
		for(MService service: servicesMods){
			if(service.getQuantity()>0)sortedServices.addFirst(service);
			else sortedServices.addLast(service);
		}
		//Creo il modulo dei servizi in base alla mappa ottenuta
		return new ModCollectionViewer(this, sortedServices, "BUDGET_SERVICES", "BUDGET_SERVICES", this.getViewType(),ModCollectionViewer.HIDE_ADD,ModCollectionViewer.HIDE_REMOVE);
	}
	@Override
	protected CPanel getReadOnlyPanel(boolean isSelected) {
		return this.getDefaultPanel();
	}
	@Override
	protected CPanel getWritablePanel(boolean isSelected) {
		return this.getDefaultPanel();
	}

	@Override
	public CPanel getInListPanel(boolean isSelected) {
		return CModules.formatForList(request.getContent().getCustomer().getName()+" "+request.getContent().getCustomer().getSurname(),
				CWords.getWord(request.getContent().getEvent().getEventType().name())+	
				"<p>"+CWords.getWord("BUDGET_TOTAL_COST")+": "+CWords.getWord("CURRENCY")+ this.getContent().getTotal()+"</p>",
				isSelected);
	}
	@Override
	protected void beforeFireChange(Module<?> mod) {
		this.setContent(
				new Budget(
				this.getContent().getId(), 
				adjustements.getContent(),
				this.getContent().getTotalCostWhitoutAdjustment(),
				lastDate.getContent(), 
				request.getContent(), 
				getServicesSelected()
		));
	}
	//Ottiene la collezione dei servizi ottenuti
	private Collection<Service> getServicesSelected(){
		/*Crea una collezione con i servizi selezionati (Con ripetizioni in caso di quantità>1)*/
		LinkedList<Module<?>> servicesMods= new LinkedList<Module<?>>(allowedServices.getContent());
		LinkedList<Service> selectedServices=new LinkedList<Service>();
		for(Module<?> mserv: servicesMods){
			if (mserv instanceof MService){
				MService msrv=(MService) mserv;
				for(int i=0;i<msrv.getQuantity();i++){
					selectedServices.add(msrv.getContent());
				}
			}
		}
		return selectedServices;
	}
	@Override
	protected void afterFireChange(Module<?> mod) {}	
	@Override
	protected CPanel getOneLinePanel(boolean isSelected) {
		CPanel panel=new CPanel();
		panel.add(new CLabel(this.getTag()+":" 
				+this.request.getContent().getEvent().getEventName()+
				" "+CWords.getWord("CURRENCY")+
				" "+this.adjustements.getContent()));
		return panel;
	}
	
	public static final int VIEW_LESS=0;
	public static final int VIEW_MORE_LESS=1;
	private ModCollectionViewer allowedServices;
	private MRequest request;
	private Collection<Service> allServices;
	private ModTextField serviceTotal;
	private ModCalendar lastDate;
	private ModDoubleTextField adjustements;
	private ModTextField total;
}
